package by.bsu.rfe.belianko.euniversity.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.log4j.Logger;

import by.bsu.rfe.belianko.euniversity.constants.ErrorMessages;
import by.bsu.rfe.belianko.euniversity.constants.LoggerMessages;
import by.bsu.rfe.belianko.euniversity.constants.SQLQueries;
import by.bsu.rfe.belianko.euniversity.exceptions.ConnectionExceptions;
import by.bsu.rfe.belianko.euniversity.exceptions.DaoTechnicalException;
import by.bsu.rfe.belianko.euniversity.pool.ConnectionPool;

/**
 * Load admission state from DB using pool of JDBC connections.
 * 
 * @author Vitali_Belianko
 * 
 */

public class AdmissionDAO implements IAdmissionDAO {
	private static final String RECEIVING_IS_COMPLETE = "Receiving is complete";
	private static final String STATE = "state";
	private static final Logger LOGGER = Logger.getLogger(AdmissionDAO.class);
	private static ConnectionPool connectionPool;
	private static AdmissionDAO instance;

	public static AdmissionDAO getInstance() {
		if (instance == null) {
			instance = new AdmissionDAO();
		}
		return instance;
	}

	private AdmissionDAO() {

	}

	/**
	 * Returns current state of admission from database.
	 * 
	 * @return state="complete" or null
	 * 
	 * @throws DaoTechnicalException
	 * 
	 * 
	 */
	@Override
	public String getAdmissionState() throws DaoTechnicalException {
		try {
			connectionPool = ConnectionPool.getInstance();
		} catch (ConnectionExceptions e) {
			LOGGER.error(e.getMessage());
			throw new DaoTechnicalException(ErrorMessages.CAN_NOT_GET_ACCESS_TO_CONNECTION_POOL, e);

		}
		Connection connection = null;
		try {
			connection = connectionPool.getConnection();
		} catch (ConnectionExceptions ex) {
			LOGGER.error(ex.getMessage());
			throw new DaoTechnicalException(ErrorMessages.CAN_NOT_GET_CONNECTION, ex);
		}

		LOGGER.debug(LoggerMessages.RECEIVE_CONNECTION);

		PreparedStatement statement = null;
		ResultSet resultSet = null;
		String state = null;
		try {
			statement = connection.prepareStatement(SQLQueries.GET_ADMISSION_STATE);

			LOGGER.debug(LoggerMessages.TRYING_EXECUTE_QUERY);

			try {
				resultSet = statement.executeQuery();

				LOGGER.debug(LoggerMessages.EXECUTE_QUERY);

				while (resultSet.next()) {
					state = resultSet.getString(STATE);

					LOGGER.debug("Receive the state of admission");

				}

			} catch (SQLException e) {
				LOGGER.error(e.getMessage());
				throw new DaoTechnicalException(ErrorMessages.CAN_NOT_EXECUTE_QUERY, e);
			}
		} catch (SQLException e) {
			LOGGER.error(e.getMessage());
			throw new DaoTechnicalException(ErrorMessages.CAN_NOT_CREATE_STATEMENT, e);
		} finally {
			if (resultSet != null)
				try {
					resultSet.close();
				} catch (SQLException e) {
					LOGGER.error(e.getMessage());
					throw new DaoTechnicalException(ErrorMessages.CAN_NOT_CLOSE_RESULT_SET, e);
				}
			if (statement != null) {
				try {
					statement.close();
				} catch (SQLException e) {
					LOGGER.error(e.getMessage());
					throw new DaoTechnicalException(ErrorMessages.CAN_NOT_CLOSE_STATEMENT, e);
				}
			}
			connectionPool.releaseConnection(connection);
		}

		return state;

	}

	/**
	 * Set admission state = "complete" in DB.
	 * 
	 * @throws DaoTechnicalException
	 * 
	 * 
	 */
	@Override
	public void completeReceiving() throws DaoTechnicalException {
		try {
			connectionPool = ConnectionPool.getInstance();
		} catch (ConnectionExceptions e) {
			LOGGER.error(e.getMessage());
			throw new DaoTechnicalException(ErrorMessages.CAN_NOT_GET_ACCESS_TO_CONNECTION_POOL, e);

		}
		Connection connection;
		try {
			connection = connectionPool.getConnection();
		} catch (ConnectionExceptions ex) {
			LOGGER.error(ex.getMessage());
			throw new DaoTechnicalException(ErrorMessages.CAN_NOT_GET_CONNECTION, ex);
		}
		LOGGER.debug(LoggerMessages.RECEIVE_CONNECTION);
		PreparedStatement statement = null;

		try {
			statement = connection.prepareStatement(SQLQueries.COMPLETE_RECEIVING);

			LOGGER.debug(LoggerMessages.TRYING_EXECUTE_QUERY);

			try {
				statement.executeUpdate();

				LOGGER.debug(RECEIVING_IS_COMPLETE);

			} catch (SQLException e) {
				LOGGER.error(e.getMessage());
				throw new DaoTechnicalException(ErrorMessages.CAN_NOT_EXECUTE_QUERY, e);
			}
		} catch (SQLException e) {
			LOGGER.error(e.getMessage());
			throw new DaoTechnicalException(ErrorMessages.CAN_NOT_CREATE_STATEMENT, e);
		} finally {

			if (statement != null) {
				try {
					statement.close();
				} catch (SQLException e) {
					LOGGER.error(e.getMessage());
					throw new DaoTechnicalException(ErrorMessages.CAN_NOT_CLOSE_STATEMENT, e);
				}
			}
			connectionPool.releaseConnection(connection);
		}

	}

}
